feat: persist Telegram files in R2 - #151
Merged
Merged
Conversation
- Add sender-scoped R2 storage and a persistent SQLite catalog - Restore durable files into ephemeral Telegram sandboxes - Add private file tools, prompt metadata, tests, and evals
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d9fa71791b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Preserve temporary processing when R2 configuration is invalid - Replace expired hashes before cataloging identical uploads - Avoid hard-coded retention promises in fallback messages
- Resolve container.py/privacy.py/registry.py conflicts by keeping both R2 file storage and Google health storage - Merge telegram bot.py refactor (album buffer, settings menu extraction) with R2 attachment ingest/session changes - Merge test_registry.py and test_telegram_bot.py additions from both branches - Regenerate uv.lock via `uv lock` instead of hand-editing
- Default R2_FILE_RETENTION_DAYS to unset, meaning files never expire until the bucket itself is deleted - Allow expires_at to be NULL in the catalog schema and treat NULL as never-expiring in all lookup queries - Keep bounded retention available by setting R2_FILE_RETENTION_DAYS explicitly (1-3650 days) - Update .env.example and docs to describe the new default - Add storage/service/config tests for the infinite path
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Persist supported Telegram attachments in private Cloudflare R2 while keeping
a sender-scoped SQLite catalog and a working copy in the active sandbox.
Why
Telegram attachment bytes currently disappear when an ephemeral sandbox dies.
Users need durable, private storage that the agent can discover and restore into
a replacement sandbox without exposing R2 credentials, keys, or other users'
objects.
How
deterministic orphan reconciliation, and infinite retention by default —
files are kept until the bucket is deleted, unless
R2_FILE_RETENTION_DAYSis explicitly set to a bounded window (1-3650 days).
sandbox working paths for documents, photos, audio, video, and voice.
limits before storage.
untrusted prompt data.
Document that an R2 lifecycle rule is only needed if
R2_FILE_RETENTION_DAYSis set, to keep the bucket in sync with the bounded-retention catalog.
Tests
uv run ruff format --checkuv run ruff checkuv run mypy .uv run pytest --cov=src— 1,587 passed, 1 skipped, 100% coverageRelated Issues
Fixes #150